package com.alex.maze.entities;

import com.alex.maze.graphics.Sprite;
import com.alex.maze.level.Level;
import java.util.ArrayList;
import java.util.List;

public class Entity
{
    public List<Sprite> sprites = new ArrayList<Sprite>();
    
    public double x, z, rot;
    public double xa, za, rota;
    public double r = 0.4;
    
    public Level nivo;
    
    private int xTileO = -1;
    private int zTileO = -1;
    
    private boolean removed = false;
    
    public final void azurirajPoziciju()
    {
        int xTile = (int) (x + 0.5);
        int zTile = (int) (z + 0.5);
        
        if (xTile != xTileO || zTile != zTileO)
        {
            nivo.getBlock(xTileO, zTileO).removeEntity(this);
            xTileO = xTile;
            zTileO = zTile;
            System.err.println("Move to (x pos) ---> " + xTileO + " and move to (y pos) ---> " + zTileO);
            nivo.getBlock(xTileO, zTileO).addEntity(this);
        }
    }
    
    public boolean isRemoved()
    {
        return removed;
    }
    
    protected void remove()
    {
        nivo.getBlock(xTileO, zTileO).removeEntity(this);
        removed = true;
    }
    
    
    
    protected void move()
    {
        int xSteps = (int) (Math.abs(xa * 1000) + 1);
        for (int i = xSteps; i > 0; i--)
        {
            double xxa = xa;
            if (jeSlobodan(x + xxa * i/xSteps, z))
            {
                x += xxa * i/xSteps;
                break;
            }
            else
            {
                xa = 0;
            }
        }
        
        int zSteps = (int) (Math.abs(za * 1000) + 1);
        for (int i = zSteps; i > 0; i--)
        {
            double zza = za;
            if (jeSlobodan(x, z + zza * i/zSteps))
            {
                z += zza * i/zSteps;
                break;
            }
            else
            {
                za = 0;
            }
        }
    }

    protected boolean jeSlobodan(double xx, double yy) // Kolizija btw.
    {
        int x0 = (int) (Math.floor(xx + 0.5 - r));
        int x1 = (int) (Math.floor(xx + 0.5 + r));
        
        int y0 = (int) (Math.floor(yy + 0.5 - r));
        int y1 = (int) (Math.floor(yy + 0.5 + r));
        
        if (nivo.getBlock(x0, y0).blockMotion)
        {
            return false;
        }   
        if (nivo.getBlock(x1, y0).blockMotion)
        {
            return false;
        }
        if (nivo.getBlock(x0, y1).blockMotion)
        {
            return false;
        }
        if (nivo.getBlock(x1, y1).blockMotion)
        {
            return false;
        }
        
        int xc = (int) (Math.floor(xx + 0.5));
        int zc = (int) (Math.floor(yy + 0.5));
        
        int rr = 2;
        
        for (int y = zc - rr; y <= zc + rr; y++)
        {
            for (int x = xc - rr; x <= xc + rr; x++)
            {
                List<Entity> es = nivo.getBlock(x, y).entities;
                for (int i = 0; i < es.size(); i++)
                {
                    Entity e = es.get(i);
                    
                    if (e == this)
                    {
                        continue;
                    }
                    
                    if (e.blocks(xx, yy, r))
                    {
                        return false;
                    }
                    
                }
            }
        }
        
        return  true;
    }
    
    public boolean use(Entity source)
    {
        return false;
    }

    public void azuriraj()
    {
        
    }

    public boolean blocks(double x2, double z2, double r2)
    {
        System.err.println("Blocks?");
        if (x + r <= x2 - r2)
        {
            return false;
        }
        if (x - r >= x2 + r2)
        {
            return false;
        }
        if (z + r <= z2 - r2)
        {
            return false;
        }
        if (z - r >= z2 + r2)
        {
            return false;
        }
        
        return true; // Samo kolizija za jedan objekat?
    }
    
    public boolean contains(double x2, double z2)
    {
        System.err.println("Contains?");
        if (x + r <= x2)
        {
            return false;
        }
        if (x - r >= x2)
        {
            return false;
        }
        if (z + r <= z2)
        {
            return false;
        }
        if (z - r >= z2)
        {
            return false;
        }
        
        return true; // Samo kolizija za jedan objekat?
    }
}
